#ifndef MAINWINDOW_H
#define MAINWINDOW_H
/*
 * 修改记录
 * 版本       时间          内容
 * 2.0      24.11.29    PH、ORP、水温的测试可配置
*/
#include <QMainWindow>
#include <QDebug>
#include <QThread>
#include <QTimer>
#include <QDialog>
#include <QMovie>
#include <QString>
#include <QThread>
#include <QMutex>

#include <QCoreApplication>
#include <QDataStream>
#include <QTableWidget>
#include <QTableWidgetItem>

//引入qt中串口通信需要的头文件
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>

//#define EN_DB_TIMER
//#define EN_DB_COM
//#define EN_DB_RECV_BYTE
#define EN_DB_RECV_STR
//#define EN_GIF_DISPLAY

#define EN_LANGUAGE_ENGLISH (0)         // 英语

#define JUDGE_PASS_NUM 5
#define JUDGE_FAIL_NUM 50
#define SOFT_VER        "2.0"
#if (EN_LANGUAGE_ENGLISH == 1)
#define TITLE_STR   (tr("InverClear Testing Tool V1.12"))
#else
#define TITLE_STR   (tr("盐氯机M款量产测试软件 V")+SOFT_VER)
#endif



typedef enum {
    R_FLAG_SERIAL_ERR = 0,
    R_FLAG_SERIAL_CONNECT_ERR,      // 串口连接错误
    R_FLAG_RS485_ERR,
    R_FLAG_TEST_TIME_OUT,
    R_FLAG_TEST_PASS,
    R_FLAG_TEST_FAIL
} result_flag_t;

typedef struct{
    bool connect_flag;
    int com_state;      // 状态
    int len;
    QByteArray recv_buf;
    QByteArray send_buf;
}ComStr;

typedef struct{
    //QString ID;
    int dev_id;             // 设备id
    int mode;               // 工作模式，3：工厂模式
    QString version;        // 软件版本
    float ph;               // PH值
    short orp;              // ORP值
    float waterTemp;        // 水温
    float bodyTemp;         // 机箱温度
    float sj;               // SJ值
    float si;               // SI值
    float sv;               // SV值
    bool point;             // 干接点/水流开关
    bool wifi;              // WIFI状态
    bool time;              // 时钟芯片状态
    bool touch[5];          // 按键状态，出现过按下的就保持
    bool rs485;
    bool pump;
    bool sr;
    bool rc;
    int size;               // 电解片规格
    bool buzzer;
    bool motor;
    char soft_ver[48];      // 软件版本
    int soft_ver_i;         // 软件版本
    int product_type;       // 产品类型
    int temp1_int;          // 水温温度整型值
    int temp2_int;          // 机箱温度整型值
    unsigned int temp1_err;      // 水温温度错误次数
    unsigned int temp2_err;      // 机箱温度错误次数
    unsigned int point_ok_cnt;   // 干接点ok次数，用于防抖
    unsigned int point_fail_cnt;
    unsigned int buzzer_ok_cnt;  // 蜂鸣器ok次数，用于防抖
    unsigned int motor_ok_cnt;   // 电机ok次数，用于防抖
    //bool led;
    uint32_t modbus_addr;
    uint32_t control_mode;
    uint32_t cell_model;
    uint32_t ic_id[4];

    int32_t info_flag;
    int32_t test_result;

    int32_t setting_flag;
    uint32_t setting_modbus_addr;
    uint32_t setting_control_mode;
    uint32_t setting_cell_model;
} DeviceData;

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

typedef void (*thread_fun)(void *arg);

class QDemoThread : public QThread
{
    Q_OBJECT

public:
    QDemoThread(QObject* parent = nullptr);
    QDemoThread(thread_fun fun, void *arg);
    ~QDemoThread();

protected:
    void run() override;

public:
    void stop();

private:
    bool flag;
    void *m_arg;
    thread_fun m_fun;

};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    bool SetElectrolyzerIndex(int index);
    void SetTestMode(int mode);
    void SetKeepSettingFlag(int flag);
    void InitSerialPortList(void);
    //int GetSerialPortErr(void);
    bool CheckSerialPortReady(const QString &port_name);
    //int ModbusReadInputBits(int addr, int nb, uint8_t *dest);
    //int ModbusReadRegisters(int addr, int nb, uint16_t *dest);
    //int ModbusWriteRegister(int addr, uint16_t val);
    //int ModbusReadInputRegisters(int addr, int nb, uint16_t *dest);
    void UpdateDataDisplay(void);
    void TestDataResultDisplay(void);

    //QByteArray &GetSerialPortRecvBuf(void);
    //void ClearSerialPortRecvBuf(void);
    void GetDeviceData(void);
    void InitDevcieData(void);
    void JudgeTimeDisplay(void);
    void SoftVersionDisplay(void);
    void ProductTypeDisplay(void);
    void KeyDisplay(void);
    void LcdDisplay(void);
    void InitLcdDisplay(void);
    void InitTextBrowser(void);
    bool TestPrepare(void);
    void TestStepCtrl(void);
    void RetryOpenSerial(void);
    void TestResultShow(uint32_t mode);
    void InfoDisplay(void);
    void ORP_Enable_Set(bool s);
    void PH_Enable_Set(bool s);
    void WaterTemp_Enable_Set(bool s);
signals:
    void SerialPortErrorDealSignal(QSerialPort::SerialPortError error);
    void TestStepSignal(int flag);
    void TestResultSignal(int flag);



private slots:
    void on_OpenSerialButton_clicked();
    void on_RefreshSerialButton_clicked();

    void on_SendSerialButton_clicked();

    void on_ClearTxButton_clicked();

    void on_ClearRxButton_clicked();

    void on_TestButton_clicked();
    void SerialPortErrorOccurred(QSerialPort::SerialPortError error);
    void SerialPortErrorDealSlot(QSerialPort::SerialPortError error);
    void TestResultSlot(int flag);
    void TestStepSlot(int flag);

    void ReadData();
    //int SendData(void *buf, int len);
    void Timer_Task1();
    void result_judge();
    void result_display();
    void find_com_loop();
    void test_step_ctrl();
    void com_send_heartbeat();
    void lcd_display();
    void clear_lcd_display();
    void table_widget_cell_clicked(int row, int column);

    void on_help_btn_clicked();

private:
    Ui::MainWindow *ui;
    //QSerialPort *serial;//全局的串口对象
    QTimer *myTimer;// 定时器对象
    QTimer *myTimer2;// 定时器对象
    QDialog *dialog;
    QMovie *movie_testing;
    QMovie *movie_point;
    QMovie *movie_wifi;
    QMovie *movie_touch;
    QMovie *movie_time;
    QMovie *movie_rs485;
    QMovie *movie_pump;
    char result[14];
    int test_step;
    int cnt_p[14];
    int cnt_f[14];
    int judge_time;
    int com_err_cnt;
    int test_mode;//测试模式
    QString recv_str;
    bool m_orpEnable;
    bool m_phEnable;
    bool m_waterTempEanble;
//    ComStr com;
    QDemoThread *modbus_thread;
//    QMutex dev_mutex;
//    QMutex serial_mutex;
    bool err_flag;
    QTableWidget *p_table_widget;
};

void* memset(void *s,int ch,size_t n);
void Delay_MSec(unsigned int msec);
QByteArray HexStringToByteArray(QString HexString);
QString ByteArrayToHexString(QByteArray &ba);

#endif // MAINWINDOW_H
